FDS loader software documentation (revision 2.0)

Project concept, research, architecture, development, and this documentation exclusively by Brad Taylor (big_time_software@hotmail.com). Other NES/FC/FDS related work and information can be found at http://nesdev.parodius.com.

Spelling mistakes in original document corrected by Christopher Cox (c.cox@sasktel.net).

All information that lead to the development of this project came from my "FDSTECH.TXT" document, and documents mentioned therein.

 Note: this document uses text mode characters. if you are using a windows program like notepad to view this document in, using "terminal" style fonts will display the full ASCII character set correctly.


Disclaimer
----------
 This product is provided AS IS. Make this project/use this product at your own risk. This does not suggest the product is faulty, it simply means that I (Brad Taylor) am not liable for any damages it may cause you, directly or indirectly.


Document contents
-----------------
Revision history
Why I did this project
Software description
Physically building the project
Software improvements (from previous version)
Software compatibility
Why the program may not work
Known bugs
Disk reprogramming problems
Pinout diagrams
Wiring chart
Using the software


+----------------+
|Revision history|
+----------------+
r'vsn	date		additions/comments
-----	----		------------------
2.0	14/11/02	-major rewrite of FDSLOADR's data uploading code so that it will run properly regardless of prior timing issues
			-added/removed/changed a few sections in this documentation in accordance to changes made to the FDSLOADR software

1.1	18/10/02	-seperated "software comp./known bugs" into 2 sections
			-"Disk reprogramming problems" section

1.02	07/5/2002	spelling corrections made

1.01	02/5/2002	-note ($) in wiring section
			-revision history

1.00	29/4/2002	public release


+----------------------------------------------------------------------+
|Why I did this project (and how some software implementation was done)|
+----------------------------------------------------------------------+
 The reason I started this project was because I have owned an FDS since 1994, and had played some great games on it (especially great sounding games). Today, with some of the disks I own dating back to 1987, these disks are getting very old, and are starting to fail more and more often. Furthermore, experiments I made on the disk drive during a time when I was not so wise have left it in less than perfect shape (besides this, I've heard plenty of stories on the 'net about how their FDS disk drive belts are worn). Needless to say, the disk drive, and the games, will all one day stop working.

 Suffice it to say, there is nothing that can really go wrong with the RAM adaptor (well, mine is intact, anyway). So I thought of setting up a project that interfaced the FDS's RAM adaptor with a personal computer in place of the disk drive. The PC would upload FDS games off the hard disk to the RAM adaptor via control (emulation) software. This would allow the FDS RAM adaptor hardware to still be useful (meaning using a REAL NES/FC to play the games on), while eliminating the cumbersome (and mostly unreliable) FDS storage system (in other words, those proprietary 2.5" disks). As a bonus to NES developers who have a RAM adaptor, this project would allow them to code their NES programs (in *.FDS form) on their PC, and use this project to easily upload it for execution on a real NES/Famicom.

 The project began (August '01) with reverse engineering the disk drive's operation, the data protocol it used for serial communication, and the low level fashion in which data was being stored on the disk. This time period took about 1.5 months, which mostly consisted of the electronic projects I had to set up to in order to interface the disk drive with the PC, and then the software I had to write to help make sense of the data I captured.

 The second step was cracking the CRC algorithm which was being used to maintain the data integrity of files on the disks. This was a very difficult task to complete because only one FDS technical document I know of even mentioned the existence of a CRC check, which had left no details on the calculation/generation of it. This is understandable, since most FDS documents out there are geared towards the development of full-blown FDS emulators, which include RAM adaptor emulation (which makes the implementation of the CRC mechanism unnecessary).

 And yet, without the CRC algorithm, the project was still just a pipe dream. I spent about half-a-month researching CRC's, trying to make sense out of documentations that barely described software implementation. The biggest mysteries I had to solve in regards to the disk system's CRC quantity were 2 things: the bit ordering, and the polynomial used. I was first trying out all combinations of these aspects on test data (which I acquired from partially reading a real FDS disk) to try to arrive at a CRC which matched the one recorded on the disk. Then my friend told me that if I include the CRC quantity stored on the disk in the CRC calculation, the result will be 0 if the data agrees with the CRC. That's when I cracked the algorithm, and the polynomial it used. In fact, it turned out that the poly used was a pretty popular 16-bit one.

 After this, I was ready to make my first attempt at putting together a project which would emulate the disk drive unit of the FDS.

 The first software I wrote (October '01) had to rely on external hardware (some off-the-shelf digital electronic circuitry) for transferring data between the RAM adaptor, and the PC. This hardware consisted of a FIFO (for buffering the bursts of data the emulation software sent out), and the serializer (mainly an 8-bit shift register, and an XOR gate; used for the converting of data to the serial communications protocol native to the RAM adaptor). Eventually I lost interest in the project because the use of the external hardware made the project unconventional for any kind of public release, which is why I ultimately wanted to finish the project (I wanted anyone to benefit from this project, not just people with an electronics background). Furthermore, I currently had no provisions for handling the data the RAM adaptor would send out when it wants to write (save) to the disk. Enabling this data capture ability would require even more hardware, which conflicted with the goals of my project.

 In January '02, I revised the project, and started investigating methods as to how software could emulate the hardware I was once using. The biggest problem was sending the serial data to the RAM adaptor at a constant rate (96.4 kHz, within 10%).

 I first thought about using the PC's programmable interval timer (PIT) to fire off 192800 interrupts per second (where I would then update the serial data signal being sent out to the RAM adaptor), but I soon realized that this impractical solution would not give reliable results.

 My next stab at the problem was taking advantage of the built-in delay when any port is written to. The parallel port registers were my main target because it's external availability could make a connection between it and the RAM adaptor easy, and it's ISA bus PIO timing is a long-time established industry standard, so it's access speed is more or less guaranteed to be the same across old & new computers. While a single "OUT" to this port wouldn't generate the complete delay I needed, a few "OUT"s in a row would. This proved to be a reliable and practical method of tackling the aforementioned problem (please see the "Software improvements" section, for a follow-up on updated related info).

 The final step was support for interpreting the serial data that the RAM adaptor would send out of it when a write to disk is to be made. This was by far the hardest thing to implement exclusively by software.

 It turns out that the write data the RAM adaptor sends out of itself is made up of pulses. This is no different than how data is stored on FDS disks, but from a PIO standpoint, the status of a pulse is impossible to read reliably, unless the pulse frequency (RAM adaptor generated) is in sync with the read frequency (a CPU read from a parallel port register), which it was of course not.

 To overcome this, I decided to tie the "write data" signal to the printer port's IRQ7 line, thus generating an interrupt upon every pulse sent out. What the software would do is keep track of the elapsed time between interrupts, which would then be used to determine the length of the pulse, and finally to the proper bit interpretation of the pulse.

 Tying the "write data" signal to the IRQ line meant a maximum generation of 96400 interrupts a second, but apparently the PIC is able to handle this frequency of interrupts accurately enough for the purposes of bit interpretation IF all other interrupts are disabled.

 Finally, a method of keeping track of elapsed time between the 96.4 kHz (max.) interrupt intervals had to be implemented.

 First I decided to use a CPU register as a counter, which would count up at the maximum speed the CPU would allow. When an interrupt would occur, the count would be read, the appropriate bit would be interpreted based on that count, and the counter would be reset to 0 when the interrupt routine was done.

 The main caveat this idea had was that the accumulated count would not take into account interrupt overhead (since the counter only runs when the interrupt isn't). In this case, interrupt overhead could not be ignored- since at least 1 port write is required, and that is to the PIT- a legacy ISA hardware device (which consumes about 18% of the available time between pulse interrupts). Finally, precalculating overhead meant some initial performance measuring, which I thought was a bit too excessive for the task at hand (and still would yield an overhead calculation not guaranteed to be 100% accurate).

 Eventually, I stumbled upon a great x86 instruction which was perfect for keeping track of elapsed time: RDTSC (read time stamp count). This instruction returns the current 64-bit count of an on-going counter internal to the CPU which increments on every clock cycle. The only problem with deciding to use this instruction was that it is implemented in Pentium+ CPUs only. I ultimately decided to go with it, seeing that Pentium systems have been around long enough already (10 years).

 RDTSC ensured the most accurate way of keeping track of elapsed time between interrupts, but had the huge caveat of the CPU count range for a pulse varying widely across PC systems. For the time being I stuck with it, since I was more concerned with getting my program to read in data properly, than my program's compatibility with other systems.

 While acquiring data issued out by the RAM adaptor was flawless, after deciding to include support in my program for an additional interface with the FDS disk drive unit, data read from a genuine FDS disk was not interpreted very well by my program.

 Sometimes the contents of a disk could be read correctly, other times there might be the odd spot in the downloaded data where just one pulse was misinterpreted, which would then cause all the subsequent data in the file on the disk to all be converted incorrectly.

 The reason this happened was because the FDS disk drive's disk rotation speed or RPM is not constant. In fact, when a disk is being scanned, the RPM can vary up to 15% outside the speed it's supposed to turn at. This is mainly caused by friction on the disk being greater in some spots than others. Because of this "drift", the program may see 1's as 0's and vice-versa, simply because the program's interpretation of pulses is based on a constant and therefore expected range of time units between pulses to elapse.

 So, you may now be asking as to how the RAM adaptor deals with this drift. The RAM adaptor is able to dynamically adjust the transfer rate which it interprets data read from the disk drive at based on the frequency of the previous pulses sent to it. For example, let's say that for the RAM adaptor to interpret a "0", it expects a range of 15..24 elapsed time units to go by before receiving a pulse, and a range of 25..34 units for a "1". A pulse is then received after 22 elapsed time units. The RAM adaptor interprets it as a 0, but now the definition of "0" is changed to 17..26, and a "1" is now in the range of 27..36 time units (actually, the ranges would increase by an appropriate factor, and not by simply adding/subtracting the difference, but this goes beyond my simple explanation). Note that the RAM adaptor's flexibility in this dynamic adjustment is limited (in other words, it won't be able to tolerate a huge amount of transfer rate drift. This may explain why certain FDS disks stop working over time).

 To allow my program to interpret data with a varying transfer rate, a similar technique had to be implemented into my program. However, my implementation had to be able to automatically detect the current transfer speed of the data sent to it, without having to rely on ANY initial elapsed time unit range definitions for 0's or 1's. This was made possible by knowing that the first disk data which the program acquires before anything else is "GAP" data. Knowing that this data is consisted entirely of 0's, the first range definitions could be calculated after obtaining the first elapsed time count in the GAP period. Calculations are then continued throughout the entire data acquisition process, to ensure that any transfer rate drift can be compensated for. Naturally, with this mechanism implemented, CPU clock speed becomes immaterial to the program for data interpretation purposes.

 Only little success came with the implementation of the aforementioned algorithm. Sometimes data acquisition would go flawlessly, while other times it would not. After some investigating, I realized that when a pulse is sent to the printer port's IRQ pin, the time at which the CPU acknowledges is sometimes delayed. These delays (which occur about 10% of the time, at 96.4kHz interrupt intervals), translate into little "spikes", when compared to the elapsed time of ordinary pulses which were not postponed. It was these spikes that were screwing up the way my algorithm worked, since the algorithm was making pulse range calculations based only on the previous one read in. The fix was to maintain a buffer recording the length's of the last 16 pulses or so read in, so that a range calculation can be made based on the average length of pulses stored in the buffer. And while doing this makes the range calculations almost insensitive to the "spikes" described before, it still allows the rate at which data can be acquired at to vary over some time.

 So there you have it. What you're looking at is 2 months of research/reverse engineering, and 4+ months of software development & documentation. This is the biggest NES-related project I've done to date (probably reverse engineering and documenting the NES's sound channels was the second). I hope you've enjoyed reading this history as much as I did making it, and I certainly hope you'll enjoy the project I've worked my ass off to finish.


+-------------------------------+
|Description of program/software|
+-------------------------------+
 The software this document describes has two applications, both which involve the use of the Nintendo Famicom Disk System hardware (RAM adaptor & Disk Drive unit).

 The user specifies a *.FDS file (FDS disk game image) to load into the software via a command parameter. Then by means of the parallel port, depending on what FDS hardware is connected to the parallel port, the software can communicate with either the RAM adaptor OR the disk drive unit.

 When the RAM adaptor is used, the software acts as a full-blown Famicom Disk System Disk Drive emulator. Data from the loaded FDS disk game image(s) can be sent or received at the RAM adaptor's discretion. Disk data that is modified by the RAM adaptor can then be optionally saved back to the originally specified *.FDS file.

 When the disk drive unit is used, the software can be used to read OR reprogram the contents of any disk in the drive. The software controls which operation to carry out (a read or reprogram of the disk in the drive). In this case, the *.FDS file specified prior to running the program will either serve as the source or destination for the contents of the disk image(s).


+-------------------------------+
|Physically building the project|
+-------------------------------+
 NO external electronic hardware is required for making this project work. Only direct electrical connections from the parallel port to the FDS hardware are made (these connections will be revealed in the "Wiring chart" section). However, some electronics skill will be required on your part to finish this project. For making the few wiring connections required, anyone who has entry-level soldering/wiring experience shouldn't find this part too hard. But you will be responsible for making/obtaining the miscellaneous connectors used by the project, which may involve some problem solving, ingenuity, or possibly even hard decisions. There are no pictures or step by step guide provided in this document for completing any of the hardware-related steps of the project, but hopefully the pinout figures, wiring chart, and my suggestions will be sufficient. The physical implements required to complete this project are as follows:

 - FDS hardware (RAM adaptor or/and disk drive).

 - Soldering iron & solder (since you'll most likely want to solder up your connections).

 - A male-style 25 pin D connector, for plugging into your computer's printer/parallel port (a good source for this part is from the 25 pin style serial port connectors, which were used on older computers).

 - Wires (for connecting the PC to the FDS hardware). Any type can pretty much be used, however the 2 types of cables I'd recommend are shielded, and ribbon. Shielded will have less interference with RF related electronics, while ribbon may be easier to work with (and probably more available, since most computer cables are ribbon, which can then be salvaged from old computers). Use a wire length you deem appropriate. To decide on the number of wires (conductors) you'll need, refer to the "Wiring chart" section.

 - An interface connector to plug into the RAM adaptor or disk drive unit. Because the RAM adaptor's connector requires somewhat of a card-edge interface, to get access to the pins, I'd recommend using a double-sided copper clad circuit board (PCB) to stick into it. The copper clad board would have to be long enough to fit all the way into the connecter, and still stick out enough for there to be room for solder pads (but generally the PCB piece will be pretty small). Also, the board will have to have 5 equidistant breaks scribed into it on each side (use a utility knife to do this, or by other means if you have them) to prevent short circuiting the pins on the connector. For gaining access to the disk drive unit's pins, the only solution may be by using the RAM adaptor's own cable. This can be done without damage by disassembling the RAM adaptor and unplugging the cable from there.

 - An optional male style 4 pin power connector, for connecting up to one of the PC's power cables. The disk drive unit requires a 5 volt direct current input (in respect to it's ground pin). This power would normally be provided by the RAM adaptor. However, in it's absence, the power will have to be provided by the PC. This wouldn't be a big deal IF the parallel port provided any power outputs. So, this power will have to be taken off one of the PC's power cables.


+---------------------------------------------+
|Software improvements (from previous version)|
+---------------------------------------------+
 Because of the way data uploads originally worked in FDSLOADR (as described in paragraph 8-10 of the "Why I did this project" section), the accurate timing of port 378h (10% tolerance) was crucial in order for the software to work properly with the FDS hardware. On the desktop PC's I benchmarked port 378's timing on, the timing seemed to be pretty constant (or at least adjustable to the point where the timing is acceptable). So I made an assumption that this aspect of the project wouldn't be a problem, and provided people the means of benchmarking port 378h for themselves (SPDETECT.COM), just in case there was a compatability issue (which I expected to occur rarely).

 After the public release of FDSLOADR late april '02 however, I recieved more than a few e-mails in regards to project troubleshooting. Specifically, the subject that kept coming up was in regards to people having a problem with getting SPDETECT to give them the green light to do the project. Timing issues seemed to be a problem with lap-top style PC's. (as I understand it) Generic Japaneese PCs were also proving to generate timing issues with my software.

 So I decided to make a long-overdue update to the FDSLOADR software. Dual 16-bit writes to port 378h are no longer being used in the program to generate the 1/(96400*2) time base that the original program relied on. As of this release, only single 8-bit port writes are being made (which is required). Carefully timed CPU loops have been implemented inbetween port writes to make up the difference in time. These CPU loops have their iteration count based on a benchmark that FDSLOADR performs every time it's launched. The benchmark is quick (half a second), so it will otherwise go unnoticed.

 Finally, these changes should now almost guarantee that FDSLOADR will work on pretty much any PC system out there, since the internal timing is now dynamically generated (there are stipulations to this. See the next 2 sections for details). Please note however, that these software architectural improvements represent the ultimate evolution of FDSLOADR. FDSLOADR represents a milestone for serial communication via software emulation, and if FDSLOADR does not work for you with this latest release, there is nothing short of external hardware which will allow it to on your current PC.


+----------------------+
|Software compatibility|
+----------------------+
 - The program in question is stored as a DOS-targeted x86 machine code binary image command file (*.COM). Therefore, OS's without COM file support cannot run the program. The software takes advantage of 386 instructions, so logically it won't run on a pre-386 computer.

 - It is STRONGLY recommended that you run FDSLOADR exclusively in DOS. It will work under windows, but because the program performs a benchmark on startup, the results of the benchmark will become tainted if windows decides to hog system resources at that time. There is no way (I know of) to indicate (to windows) that the program's priority is critical during this time. Also, if the benchmark results are tainted due to windows, the integrity of data uploads will be directly effected (which is bad, especially if you're going to be reprogramming disks).

 - Uploads rely on accurate internal CPU-based time delay loops. Simply put: the faster your system, the better. Consequentially, the lower your CPU speed is, the more software overhead influences port write timing (which compromises the accuracy of the serial bit stream the program sends out). To summarize, don't expect great results from this program if you try to run it on a bottom-end system (like a 386 running at 20MHz). For reasons that will be described in a few paragraphs, to take advantate of this software's entire palette of functionality, you should probably be running this software on at least a 5th generation x86 processor based PC.

 - During an upload process under windows (9x), all other processes halt (including mouse). Normal operation will resume when the upload finishes. This is the result of interrupts being disabled during data transfers. This cannot be avoided, since background interrupt occurrences can halt the data transfer process at any time, which is unacceptable for the accurate & reliable transmission of data.

 - Downloads do not work under windows (9x). If the program attempts to download data from the RAM adaptor/disk drive, the program will hang (although windows should remain intact). The software has been adjusted so that downloads should work within windows, but apparently windows blocks parallel port IRQs from DOS software (or, I'm just not doing somthing right).

 - Downloads require the implementation of the "RDTSC" CPU instruction (opcode 0F 31), which was officially introduced with the Pentium processor (it's possible that some late generation 486 CPU's may support this instruction). For downloads to work on a CPU w/out support for this instruction, you will have to emulate the behaviour of it yourself. As far as I know, the best (and only) hardware to use for this task is the PIT's (programmable interval timer), which can be programmed to be an on-going counter. The big reason I've avoided using the PIT for this task is because it's base count frequency is rather low at 1.19 MHz. The lower the elapsed count frequency is, the more chance the accuracy of the acquired data may be compromised (although arguably this count frequency is sufficient). The second reason is that the PIT is legacy-ISA hardware, which means extremely slow I/O access. Factor in both these things, along with a data acquisition algorithm which uses a little division & multiplication, and you can see why I'm a little skeptical about implementing this emulation, and expecting it to work reasonably well on a 486 or lesser class CPU.

 - The program only supports *.FDS files in Fan Wen's 16-byte header format. This also means that the absolute maximum quantity of data that the program can acquire from reading 1 disk is 65500 bytes. Typically, official FDS disks will contain around 57KB of data, but some pirate-hacked copies of cartridge-based games stored on disk can use 64KB+ of data. The results of trying to read a disk like this (one with more than 65500 bytes of data on it) is undefined.


+----------------------------+
|Why the program may not work|
+----------------------------+
 The program displays the measured speed (in Hertz) of your system's port 378h in the top right corner of the screen (in dark gray). Reliable uploads REQUIRE that this port speed be at least 192800 Hz (this number is derived from the base FDS xfer frequency*2). If the measured speed is less, but not less than 10%, the displayed port speed number is highlighted in cyan (and may possibly blink). FDSLOADR may still be used under this condition, but it is not recommended. If FDSLOADR measures a port speed less than 10% of the minimum standard, the program will quit unconditionally (and an error message will appear). If this is a problem, it may be possible to increase the speed at which your computer's port 378h operates at by modifying parameters found in your computer's BIOS (generally in the "chipset features" menu. 2 ways of doing this are: adjusting an "(8-bit) I/O recovery time" parameter to a minimum amount, or: decrease the PCI:ISA clock ratio (if your BIOS sports one)). Beyond this, you'll have to find another PC to try FDSLOADR on.

 If the program is having trouble downloading (acquiring) data from the disk drive unit, the disk you're trying to read may be damaged. Read my "DISKFIX.TXT" document to see how this may be correctable. Also, for reading disks with known working trouble, you will generally have better success reading accurate disk data on a faster PC system. Note that if you're still having trouble reading the disk's data after all of this, it's most likely that the data stored on it is damaged, which makes it impossible to recover accurately.

 If there is clearly no communication taking place between the software and the FDS hardware, make sure that your parallel port is enabled in the BIOS, that it's port base is at 378h, and it's IRQ base is 7. Also, double check your wiring connections.

 Finally, many people around the world have assembled this project with success, so this project is considered tried, tested & true.


+----------+
|Known bugs|
+----------+
 Because the program handles raw data from the keyboard (instead of through the BIOS), apparently problems sometimes arise when keystrokes are pressed during FDS transfers (espically when "jamming" keys during this time). The problem is that this bug seems to lock one of the keys down (i.e., shift) when the program is terminated. At the command prompt, I've found that typing "exit", and then pressing the affected key rectifies this problem. In severe (but rare) cases during FDSLOADR's execution, this bug will lock out the entire keyboard, rendering the keyboard useless. In this case, a reboot is the only solution.


+---------------------------+
|Disk reprogramming problems|
+---------------------------+
 Shortly after publically releasing this project, a few people who assembled it had contacted me with some problems in regards to reprogramming FDS disks. This is what this section will discuss.

 Years before I started developing FDSLOADR, my FDS disk drive had been in bad condition. Springs were loose, the head was misaligned (alot of games were no longer working because of this), and to top it off, I couldn't even write data onto disks anymore with it (only read). Regretfully, my entire FDS system was a big paperweight, simply because the drive didn't work well anymore.

 Only months before starting the FDSLOADR project had I thought up this idea of interfacing the PC with the RAM adaptor. I hadn't even thought of developing the project for interfacing with the FDS disk drive, since mine wasn't in much condition to make that feature very useful.

 After getting to the point where FDSLOADR was working flawlessly with the RAM adaptor hardware, I realized that the procedure for communicating with the disk drive would be almost identical. Considering that my disk drive had seen better days, I decided to integrate this functionality mostly for versatility purposes (and since it was already a ground-breaking project, I decided that adding this feature would make it an even better product).

 Of course, I had to fix up my disk drive to test the program on, so that's what I did. Several modifications were made (I completely eliminated the circuit board atop the battery compartment (and along with it, the requirement for a second power supply), plus I threw some discrete logic onto the drive mechanism's circuit board to repair the disk writing ability).

 When I tested the ability to read/write data from/to disks via my program, I had no problems. However, people on the internet who had built the project themselves had told me that they were not able to overwrite _any_ data on their existing FDS disks. It was clear to me that my drive's write features were working because I bypassed a couple of integrated circuits that were originally intended to be used to control writing (originally damaged in my case).

 Anyways, it is my opinion that Nintendo has put unneccessary circuitry inside the FDS disk drive unit (seeing that I've successfully managed to remove it without compromising any functionality), prehaps to prevent the complete rewriting of the contents of FDS disks (which explains why others who've built my project claim that rewriting FDS disks didn't work for them). Pretty much all the unneccessary circuitry is contained on the circuit board above the battery compartment (labeled "FMD POWER").

 First, the board has a electronically switchable 5-volt power supply on it. This is questionably useful, since the drive motor (which is what it's used to power) really doesn't use all that much current (~250mA during operation). I've replaced this with a medium current pnp xstr tied to the NES's main 5-volt line. The xstr switches on when the drive motor is to be activated with about a 100mV drop in voltage across the CE junction, and you'd better believe that this works just as good as Nintendo's part-wasteful (and power-wasting) independent power supply.

 Second, there's an integrated circuit (BU3213) which intercepts 2 disk control signals: "-stop motor", and "-write". This may be a microcontroller, since there's a 4MHz crystal attached to it. Anyways, I have no idea what it really does, but since it intercepts the "-write" signal (and has access to the "-ready" signal), it's a good guess that this chip is programmed to know when someone is trying to rewrite an entire disk (which is when it blocks the write signal), or simply update a file (when the write signal is allowed to pass). Either way though, you might as well consider this chip to be an FDS equivelant cicurity chip, since it serves no other purpose that I can see.

 The bottom line is that it _may_ not be possible at all to use conventional FDS disk drives to reprogram the contents of FDS disks, without having to modify the disk drive unit's circuitry. Remember, this information is based mostly on speculation, since I have no way of verifying any of it. I'm basing these hypotheses off of claims that FDS disk reprogramming attempts via my program were ineffective, the unexplainable existence of otherwise useless circuitry inside the disk drive unit, and the fact that I was able to properly rewrite FDS disk contents completely with my modified disk drive. If anyone can provide me with more information in regards to this, *please*, contact me.


+---------------+
|Pinout diagrams|
+---------------+
_____________________________________________
\                                            /
 \  13 12 11 10  9  8  7  6  5  4  3  2  1  /
  \                                        /
   \  25 24 23 22 21 20 19 18 17 16 15 14 /
    \                                    /
     ------------------------------------

 Front view of the 25 pin parallel port connector on a PC. Note that some parallel ports actually list the pin numbers by the holes, so look closely to see.


          
  
   1  3  5  7  9  B 
                    
   2  4  6  8  A  C 
  

 A front view of the RAM adaptor's 12-conductor pinout connector for plugging into the disk drive unit. Note that the disk drive's connector pinouts will be horizontally reversed compared to this diagram.


+------------+
|Wiring chart|
+------------+
 This section details the required electrical connections between the FDS hardware & the parallel port connector, to make the project work. Note that the RAM adaptor & the disk drive unit cannot be used together; only 1 of them can be physically wired up to the parallel port connector at any given time.


 Power signal wiring step
 ------------------------
 Pins 18 thru 25 on the parallel port connector are ground. It is ABSOLUTELY NECESSARY to make a connection between the computer's ground (either via these pins, or other means) and FDS pin #4. It may not be absolutely necessary to use more than 1 wire for carrying power signals like ground (like if a heavy gage wire is used), but if small-signal wires are being used for this, I totally recommend dedicating at least a few for exclusive power signal usage. This will especially be important when using ribbon cable. For example, all 8 of the parallel port's ground pins should be used and assigned to mutually exclusive wires on the ribbon cable. Also, when assigning signals to wires, try to alternate between power signal and small signal on the ribbon cable (i.e., even ribbon cable wires could be power signal, and odd wires would be for small signal).


 Small signal wiring chart
 -------------------------
 The following chart lists all 12 pinouts common between the RAM adaptor & the disk drive unit connectors (these are listed under the "FDS" field), and their ultimate electrical destination on the parallel port connector (under fields "RAM", or "DDU"). Pinouts listed under the "RAM" field are to be used ONLY when connecting the RAM adaptor to the parallel port connector, and the same for "DDU", when connecting the disk drive unit up.

 Prefixes you will find under the "signal name/description" field, are a "(R)" or "(D)" (these indicate the source of the signal, where (R) means RAM adaptor, and (D) means disk drive), and a "-" prefix, which indicates a low (0) active signal condition (as opposed to a high (1) active signal condition, which is the default). Note that information provided under this field is for reference only; it can otherwise be ignored.

 Fields that are left blank are intentionally that way, and indicates a "not applicable" condition (in other words, ignore it).

RAM	DDU	FDS	signal name/description
---	---	---	-----------------------
12	14	1	(R) -write
	 *	2	(R) VCC (+5VDC)
13	 1	3	(R) -scan media
15$		4	(R) VEE (ground)
10	 2	5	(R) data
16	11	6	(D) motor on/battery good
14	12	7	(D) -writeable media
		8	(D) motor power
 2	10	9	(D) data
 1	13	A	(D) -media set
17	15	B	(D) -ready
11	17	C	(R) -stop motor

$: This pin is an input on the parallel port. Connecting FDS pin 4 to here does NOT satisfy the ground connection condition required between the FDS hardware and the PC (as mentioned above). Therefore, this connection is IN addition to the ones mentioned in the "Power signal wiring step". Refer to paragraph 2 in the "Using the software" section for details on the role this input pin plays.

*: This pin on the disk drive unit is a power input. It will be necessary to provide this input with +5 volts direct current (with respect to ground). This voltage is available from inside the computer, via the red/black/yellow cables. The red wire carries +5VDC (connect to FDS pin #2), and the black wire is ground (connect to FDS pin #4). Note that for the disk drive to work, you will STILL have to satisfy it's original power requirements via batteries (battery compartment) or it's DC input (on the back of the unit).


+------------------+
|Using the software|
+------------------+
 Specify a valid *.FDS file (drive & path may also be specified) in the FWNES format (16 byte header) as a command parameter to the program (this is the FDS game which you will want to upload data to/download data from). If no problems are encountered (like an invalid *.FDS image, memory allocation failure, and such), the program will start up in a text-based display mode. Visuals you will see common to both operating modes is text indicating current operating mode, program hotkeys, and disk file transfer progress bars.

 The operating mode the program starts up in depends on which FDS hardware is wired up to the parallel port connector (the name of the operating mode will be the same as the FDS hardware currently connected). Technically however, it is the state of parallel port pin 15 that determines this when the program starts up, since the program has no way of detecting or authenticating the FDS hardware present.

 There will be one disk file transfer bar for every disk game present in the specified *.FDS file, and each bar will have one square for every file found on the disk (if the particular disk side has no files in it, the progress bar will be invisible, but will still be present). The bar that is highlighted indicates the currently selected disk side. Keys '1'..'9' on the keyboard (excluding NumPad keys) allows random access selection of the current disk side (but only one key (starting at '1') for every disk side present will be functional). When a data transfer starts, the currently highlighted transfer bar will dehighlight. Files that are progressively read/written then will be highlighted on the bar. Uploaded (sent) data is marked as green, and downloaded (acquired) data is marked in red.

 Other common keys used by the program are the program exit keys 'Esc' and 'F4' (F4 updates the source *.FDS file. If any changes are made to the data stored in memory (which are indicated by red colored file transfer progress squares), this key will have to be pressed to save them).


Errors
------
 Errors that occur during the download of a file will be marked on the active file transfer progress bar. There are 2 types of errors that you may see.

 The first is a CRC error, which will be marked with a purple "X". Files that fail a CRC will NOT halt the data transfer. This is done because files that proceed a CRC-failed file may not necessarily fail themselves. By reading a questionably functional disk several times, it may be possible to accurately acquire all the files off the disk, with the accurately acquired files being scattered across the multiple scans. The best way to do this is to create a *.FDS file which has a disk count set at about 8, and then in the program simply read the disk 8 times, progressively incrementing the program's active virtual disk (via the number keys) on each iteration. Of course, in the end, the user will have to reassemble the valid data on their own (this will require knowledge on the layout of the FDS's formatted disk data structures, available from Goroh's or Nori's FDS documents).

 The second is an invalid file type error. Every file on an FDS disk has a file type byte, which ultimately determines the size of the file in question. There are 4 valid predefined file types (1..4). Any values other than these will cause the immediate termination of a download process. In yellow (and sometimes appearing in gray), the file type that failed will be marked on the progress bar (the full ASCII character chart will be used to display the encountered file type, but only types 0..9 will be displayed numerically). Determining the size of a file of type #4 requires that data acquired from the most previous file be accurate. This is why a file type #4 will cause the download to be terminated, if it was proceeded by a file that failed it's CRC. Disk data acquired will always be truncated at the point the invalid file type is encountered.


RAM adaptor mode
----------------
 Visuals you will see in the RAM adaptor operating mode of the program is the disk drive's emulated status flags (media set (yellow), write enable (red), and low battery (cyan); refer to "FDSTECH.TXT" for details). The following table lists the keyboard keys that effect these flags ("X" indicates a toggle, and 0/1 indicates a binary logic state):

Key		BattLow	WriteEn	DiskSet	Notes
---		-------	-------	------- -----
Space			X	X	(1)
F1		X		X
F2		X	X

Caps		X
Alt			X
* (NumPad)			X

F3		X	X	X

(pgm startup)	0	1	1	(2)
(pgm exit)	1	0	0	(2)
(side change)		0	0 	(3)


 1: Space bar is intended to be the primary keyboard key used for toggling the DiskSet status of the drive. Other keys/combinations are provided only for isolated incidents when space bar doesn't work (I haven't come across any yet). Note that a few games I've come across require both WriteEn and DiskSet to change together, otherwise the media change will not be acknowledged. This is why I've assigned space bar to toggle both these status flags.

 2: When the program starts up, it enables disk set & write enable automatically (and appropriately disables them on exit), so that you won't have to.

 3. When a valid disk side change button is pressed, the RAM adaptor sees this as the disk being ejected from the drive. Press space bar after this to insert the disk again. Note that some games require a second or two between disk changes. For example, a game is loading up. Now you're prompted to change to side B. Naturally, you press the '2' button, which internally changes the disk pointer to side B, but also makes the RAM adaptor think that a disk has been ejected. Finally, after a brief wait, you press space bar, and the RAM adaptor starts loading the new disk side data. But if you don't wait long enough before pressing space bar, the RAM adaptor will NOT start loading again. If this happens, just simply tap space bar (to eject the media again), wait a second or two, then hit it again.


Disk drive mode
---------------
 When the program is operating in the disk drive mode, the only visual you will see is the current data transfer method (either "READ" (green) or "REPROGRAM" (red)).

 READ downloads data from the disk drive, therefore overwriting the contents of the current *.FDS disk image stored in memory (this is the default mode on program start-up). To select this mode, press any 'Alt' key. For preparing a "blank" *.FDS image with a custom # of disk sides contained in it, a valid .FDS file header will have to be created (16 bytes). The only fields that will have to be present are the FDS string, and the # of FDS game disks you'll want to download into the *.FDS file (since this cannot/will not be changed by the program). Note that F4 will have to be pressed to save the downloaded disk image(s) to the source *.FDS file before exiting the program.

 REPROGRAM uploads data (from the specified *.FDS file which gets loaded into memory) to the disk drive, therefore overwriting the contents of the current disk side in the drive. To select this mode, press the right 'Shift' key. Note that the software will ignore ANY request to reprogram a disk which is write protected. (NOTE: reprogramming attempts may be ineffective. Please see the "Disk reprogramming problems" section.)

 Transfers take place only when a disk is put in the drive (it will also happen if a disk is in the drive when the program is started). Once one scan has been made, the disk drive will stop & remain inactive until the next time a disk is (re)inserted. Pressing 'Space bar' overrides this, causing a data transfer of the currently selected transfer method. If the disk drive unit's red light doesn't turn on when a transfer is supposed to happen, this means that your disk drive battery is low. The program will indicate this condition by dehighlighting the currently active file xfer bar.


EOF